﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Collections.Generic;

namespace IndexMarkSilverlightClient.Classes
{
    public static class TreeViewExtensions
    {
        public static TreeViewItem ContainerFromItem(this TreeView treeView, object item)
        {

            TreeViewItem containerThatMightContainItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(item);

            if (containerThatMightContainItem != null)

                return containerThatMightContainItem;

            else

                return ContainerFromItem(treeView.ItemContainerGenerator, treeView.Items, item);

        }

        public static IEnumerable<TreeViewItem> AllItems(this TreeView treeView)
        {
            List<TreeViewItem> list = new List<TreeViewItem>();
            foreach (object obj in treeView.Items)
            {
                TreeViewItem item = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(obj);
                list.Add(item);
                list.AddRange(GetItems(item));
            }

            return list;
        }



        public static IEnumerable<TreeViewItem> Containers(this TreeView treeview)
        {
            return GetTreeViewItems(treeview.ItemContainerGenerator, treeview.Items);
        }



        private static IEnumerable<TreeViewItem> GetTreeViewItems(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection)
        {
            foreach (object curChildItem in itemCollection)
            {
                if (curChildItem != null)
                {

                    TreeViewItem container = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem);



                    if (container != null)

                        yield return container;



                    foreach (var treeViewItem in GetTreeViewItems(container.ItemContainerGenerator, container.Items))

                        yield return treeViewItem;
                }
            }
        }

        private static IEnumerable<TreeViewItem> GetItems(TreeViewItem item)
        {
            if (item != null)
            {
                List<TreeViewItem> list = new List<TreeViewItem>();
                if (item.Items.Count > 0)
                {
                    foreach (object child in item.Items)
                    {
                        TreeViewItem item2 = (TreeViewItem)item.ItemContainerGenerator.ContainerFromItem(child);
                        list.Add(item2);
                        list.AddRange(GetItems(item2));
                    }
                }
                return list;
            }
            else
            {
                return new List<TreeViewItem>();
            }
        }


        private static TreeViewItem ContainerFromItem(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection, object item)
        {

            foreach (object curChildItem in itemCollection)
            {

                TreeViewItem parentContainer = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem);

                if (parentContainer == null)

                    return null;

                TreeViewItem containerThatMightContainItem = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(item);

                if (containerThatMightContainItem != null)

                    return containerThatMightContainItem;

                TreeViewItem recursionResult = ContainerFromItem(parentContainer.ItemContainerGenerator, parentContainer.Items, item);

                if (recursionResult != null)

                    return recursionResult;

            }

            return null;

        }



        public static object ItemFromContainer(this TreeView treeView, TreeViewItem container)
        {

            TreeViewItem itemThatMightBelongToContainer = (TreeViewItem)treeView.ItemContainerGenerator.ItemFromContainer(container);

            if (itemThatMightBelongToContainer != null)

                return itemThatMightBelongToContainer;

            else

                return ItemFromContainer(treeView.ItemContainerGenerator, treeView.Items, container);

        }



        private static object ItemFromContainer(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection, TreeViewItem container)
        {

            foreach (object curChildItem in itemCollection)
            {

                TreeViewItem parentContainer = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem);

                if (parentContainer == null)

                    return null;

                TreeViewItem itemThatMightBelongToContainer = (TreeViewItem)parentContainer.ItemContainerGenerator.ItemFromContainer(container);

                if (itemThatMightBelongToContainer != null)

                    return itemThatMightBelongToContainer;

                TreeViewItem recursionResult = ItemFromContainer(parentContainer.ItemContainerGenerator, parentContainer.Items, container) as TreeViewItem;

                if (recursionResult != null)

                    return recursionResult;

            }

            return null;

        }

        public static TreeViewItem FindContainer(this TreeView treeView, Predicate<TreeViewItem> condition)
        {

            return FindContainer(treeView.ItemContainerGenerator, treeView.Items, condition);

        }



        private static TreeViewItem FindContainer(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection, Predicate<TreeViewItem> condition)
        {

            foreach (object curChildItem in itemCollection)
            {

                TreeViewItem containerThatMightMeetTheCondition = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem);



                if (containerThatMightMeetTheCondition == null)

                    return null;



                if (condition(containerThatMightMeetTheCondition))

                    return containerThatMightMeetTheCondition;



                TreeViewItem recursionResult = FindContainer(containerThatMightMeetTheCondition.ItemContainerGenerator, containerThatMightMeetTheCondition.Items, condition);

                if (recursionResult != null)

                    return recursionResult;

            }

            return null;

        }
    }
}
